package com.cougil.uoc.seghismed.model;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;

import com.cougil.uoc.seghismed.model.enums.GrupSanguini;

/**
 * Entitat de negoci que representa pròpiament a un Pacient
 *
 * @author Ignacio Cougil Jares
 */
@Entity
@Table(name="PACIENT")
public class Pacient extends Usuari {

	@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.EAGER)
	@JoinTable(
			name = "PACIENT_ALERGIA",
			joinColumns={@JoinColumn(name="IDPACIENT")},
			inverseJoinColumns={@JoinColumn(name="IDALERGIA")}
	)
	// al·lergies del pacient
	private Set<Alergia> alergies = new HashSet<Alergia>();

	@Column(name= "GrupSanguini", columnDefinition="integer", nullable = true)
	@Type(
			type = "com.cougil.uoc.seghismed.hibernate.GenericEnumUserType",
			parameters = {
					@Parameter(
							name  = "enumClass",
							value = "com.cougil.uoc.seghismed.model.enums.GrupSanguini")
			}
	)
	private GrupSanguini grupSanguini;

	// historial associat al pacient, que sempre en tindrà un creat
	@OneToOne(mappedBy = "pacient", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	private Historial historial = new Historial();

	public Pacient() {
		super();
	}

	public Pacient(Integer id) {
		this();
		this.setId(id);
	}

	/**
	 * Afegeix una alergia nova a la llista
	 * @param e {@link Alergia} element a afegir
	 * @return true si la llista no contenia previament l'element a afegir
	 * @see java.util.Set#add(java.lang.Object)
	 */
	public boolean addAlergia(Alergia e) {
		return this.alergies.add(e);
	}

	// no podem implementar els métodes equals ni hashCode perquè en intentar cercar després els objectes
	// d'aquest tipus en els Maps corresponents no els trobem mai (els camps no sempre estan tots informats)
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	// @Override
	// public boolean equals(final Object other) {
	// if (!(other instanceof Pacient)) {
	// return false;
	// }
	// Pacient castOther = (Pacient) other;
	// return new EqualsBuilder().appendSuper(super.equals(other))
	// .append(this.grupSanguini, castOther.grupSanguini)
	// .append(true,
	// SeghismedUtils.sonIguals(this.alergies, castOther.alergies))
	// // donat que l'historial no l'adjuntem en xifrar el pacient no l'incloem en la comparació
	// // .append(this.historial, castOther.historial)
	// .isEquals();
	// }

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	// @Override
	// public int hashCode() {
	// return super.hashCode();
	// }

	/**
	 * @return Retorna el valor de la propietat alergies
	 */
	public Set<Alergia> getAlergies() {
		return this.alergies;
	}

	/**
	 * @return Retorna el valor de la propietat grupSanguini
	 */
	public GrupSanguini getGrupSanguini() {
		return this.grupSanguini;
	}

	/**
	 * @return Retorna el valor de la propietat historial
	 */
	public Historial getHistorial() {
		return this.historial;
	}

	/**
	 * Retorna un iterador amb el conjunt d'al·lergies associades
	 *
	 * @return {@link Iterator} iterador amb el conjunt d'elements
	 * @see java.util.Set#iterator()
	 */
	public Iterator<Alergia> iteratorAlergies() {
		return this.alergies.iterator();
	}

	/**
	 * Retorna el nombre d'al·lergies associades
	 *
	 * @return nombre d'elements
	 * @see java.util.Set#size()
	 */
	public int numAlergies() {
		return this.alergies.size();
	}

	/**
	 * @param Estableix alergies com a valor de la propietat alergies
	 */
	public void setAlergies(Set<Alergia> alergies) {
		this.alergies = alergies;
	}

	/**
	 * @param grupSanguini Estableix el valor de la propietat grupSanguini
	 */
	public void setGrupSanguini(GrupSanguini grupSanguini) {
		this.grupSanguini = grupSanguini;
	}

	/**
	 * @param historial Estableix el valor de la propietat historial
	 */
	public void setHistorial(Historial historial) {
		this.historial = historial;
		if (this.historial != null) {
			this.historial.setPacient(this);
		}
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
		.appendSuper(super.toString())
		.append("grupSanguini",this.grupSanguini)
		.append("alergies", this.alergies)
		.append("historial", this.historial)
		.toString();
	}


}
